package ltd.followkba.task;

import com.kcbsdk.MyWorks.ARecordInfo;
import com.kcbsdk.MyWorks.AWorksType;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import ltd.advskin.beandbs.BUpWorks;
import ltd.followkba.MAPP;
import ltd.followkba.MDBS;
import ltd.followkba.W;
import ltd.obbphoto.release.UploadWorksTask;
import main.MAPI;

import static com.kcbsdk.wpapper.KCB_LOST_SONG_NAME;
import static com.kcbsdk.wpapper.KCB_LOST_SUB_NAME;
import static ltd.advskin.MSKIN.MLOGE;
import static ltd.advskin.MSKIN.MSTRING;
import static main.MAPI.mMyUtils;
import static main.MAPI.mMyWorks;

public class TaskEach {
    public BDbsAccount mBDbsAccount;            // 用户账号及设置
    public List<BFileBase> mRankQueue;          // 在榜单之中找到的作品队列
    public List<BFileBase> mUserQueue;          // 在评论之中找到的用户队列
    public List<BFileBase> mWorksQueue;         // 找到的作品队列
    public List<BFileBase> mBlackList;          // 不能评论的用户/已经评论过的用户作品
    public long StepTime;
    public long StepTick;
    public int SuccessQty;
    public int NormalCount;
    public int NewCount;
    public int OldCount;
    public int CareCount;
    public int GiftCount;
    public int GiftDay;                                             // 每天的礼物
    public int Hour;                                                // 每小时
    public byte gWorksType;
    public BAppUser mBAppUser;
    public BAppWorks mBAppWorks;
    public boolean SetChange;
    public long StateTick;
    public String RunState;
    public String LastState;

    public String Message;
    public String RankName;
    public BUploadPlan mBUploadPlan;
    public int[] gGiftMoney;

    public String[] NormalComment;          // 标准评论文字
    public String[] NewComment;             // 新作品评论文字
    public String[] OldComment;             // 旧作品评论文字
    public String[] CareText;               // 自动关注文字
    public String[] GiftText;               // 自动礼物文字
    public String[] AdvertText;             // 广告文字

    private boolean isPause;
    private boolean isStop;
    public int gWriteTime;

    public void MLOG(String text) {
        MSTRING(MAPI.GET_LOG_NAME(this) + text);
    }
    public TaskEach(){
    }
    public TaskEach(BDbsAccount bDbsAccount){
        mBDbsAccount = bDbsAccount;
        mRankQueue = new ArrayList<>();          // 在榜单之中找到的作品队列
        mUserQueue = new ArrayList<>();          // 在评论之中找到的用户队列
        mBlackList = new ArrayList<>();          // 不能评论的用户/已经评论过的用户作品
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (mBDbsAccount.WorksType < 32) {
                    Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
                }else {
                    Thread.currentThread().setPriority(Thread.MIN_PRIORITY+2);
                }

                mRankQueue = new ArrayList<>();         // 在榜单之中找到的作品队列
                mUserQueue = new ArrayList<>();         // 在评论之中找到的用户队列
                mWorksQueue = new ArrayList<>();         // 找到的作品队列
                gWorksType = mBDbsAccount.WorksType;
                StepTime = mBDbsAccount.SetConfig[0] * 1000;  // [0]间隔时间设置
//      tring.format("KgAppDbsA bDbsAccount.AccountName %s %s %s", bDbsAccount.AccountName, md5, bRunRam.CrcSum5));
                SuccessQty = 0;
                NormalCount = mBDbsAccount.SuccessQty;
                NewCount = mBDbsAccount.SuccessQty;
                OldCount = mBDbsAccount.SuccessQty;
                CareCount = mBDbsAccount.SuccessQty;
                GiftCount = mBDbsAccount.SuccessQty;

                NormalComment = mBDbsAccount.TextComment[W.TEXT_NORMAL].split("\n");          // 标准评论文字
                NewComment = mBDbsAccount.TextComment[W.TEXT_NEW].split("\n");             // 新作品评论文字
                OldComment = mBDbsAccount.TextComment[W.TEXT_OLD].split("\n");             // 旧作品评论文字
                CareText = mBDbsAccount.TextComment[W.TEXT_CARE].split("\n");               // 自动关注文字
                GiftText = mBDbsAccount.TextComment[W.TEXT_GIFT].split("\n");               // 自动礼物文字
                AdvertText = mBDbsAccount.TextComment[W.TEXT_ADVERT].split("\n");             // 广告文字

                mBDbsAccount.Message = "任务开始运行";
                SetChange = true;
                GiftDay = 100;              // 每天的礼物
                mainLoop();
                isStop = false;
                breakWaitting();
            }
        }).start();
    }

    public void setStop(){
        isStop = true;
        while (isStop){
            sleepWaitting(10);
        }
    }
    public void setPause(boolean pause){
        isPause = pause;
        breakWaitting();                                    // 退出任何等待
//        MLOG(String.format("RunB Cc %s",  isPause));
    }


    private void mainLoop(){
        boolean success = false;
        while (!MAPP.threadStop && !isStop) {
            checkHoldSetChange();
            if (success) {                                           // 如果完全没有写入成功，就不重置时间了
                StepTick = System.currentTimeMillis();              // 如果出错，继续上次的时间
            }
//            MLOG(String.format("RunB Cc %s(%s)%s", success, mBDbsAccount.Status,  isPause));
           if (!isPause && "ok".equals(mBDbsAccount.Status)) {
//                MLOG(String.format("RunA A进入A %s(%s)", mBDbsAccount.WorksType, mBDbsAccount.AccountName));
                if (mBlackList == null) {
                     App32.sendGifts("0", "0", 0, 0, this);  // GET_GIFT_MONEY
                    setState("加载");
                    RunUtils.loadBlackList(this);
//                    MLOG(String.format("RunA A进入B %s(%s)%s", mBDbsAccount.WorksType, mBDbsAccount.AccountName, mBlackList.size()));
                }
//                MLOG(String.format("RunD 4 %s(%s)%s(%s)%s(%s)", mBDbsAccount.AccountName, mBDbsAccount.Status, MAPP.gManageLogin, mMyUtils.getServerNumber(), StepTime/1000, Message));
                setState("查找");
                BFileBase bFileBase = findWorks();
//                MLOG(String.format("RunA %s_%s 进入C %s %s", mBDbsAccount.WorksType, mBDbsAccount.AccountName, bFileBase!=null?bFileBase.UserIdS:null, bFileBase!=null?bFileBase.WorksIdS:null));
               Message = String.format("找到作品数量%s", mWorksQueue.size());
                if (bFileBase != null) {
                    downloadFile(bFileBase);
                    setState("等写");
                    success = writeComment(bFileBase);                   // 一起计算写评论的时间
                }
                if (success) {                  // 只有写入成功才需要等待
                    setState("等待");
                    uploadAndWaitting();
                }
            }else {
                setState("空等");
                uploadAndWaitting();
                success = true;
            }
        }
    }


    private BFileBase findWorks(){
        if (mWorksQueue.size() != 0){
            BFileBase bFileBase = mWorksQueue.get(0);
            mWorksQueue.remove(0);
            mBAppUser = MDBS.getBAppUser(mBDbsAccount.WorksType, bFileBase.UserIdS);
            mBAppWorks = MDBS.getBAppWorks(mBDbsAccount.WorksType, bFileBase.UserIdS, bFileBase.WorksIdS);
            if (mBAppUser != null && mBAppWorks != null) {
                 MLOG(String.format("findWorksA BAppUser %s_%s(%s_%s_%s)%s(%s)%s", mBDbsAccount.WorksType, mBDbsAccount.AccountName, mBAppWorks.UserIdS, mBAppWorks.WorksIdS, mBAppWorks.WorksName, bFileBase.RankName, mWorksQueue.size(), mBlackList.size()));
                RankName = bFileBase.RankName;
                return bFileBase;
            }
//            MLOGE(String.format("findWorksA BAppUser %s_%s_%s(%s)%s(%s)", mBDbsAccount.WorksType, bFileBase.UserIdS, bFileBase.WorksIdS, mWorksQueue.size(), mBAppUser, mBAppWorks));
            return null;
        }
        WorksQueue.getWorksQueue(mBDbsAccount.WorksType, mWorksQueue, mBlackList, null);
        if (mWorksQueue.size() != 0) {
//                    MLOG(String.format("EchoA QueueA getWorksQueueC %s(%s)%s", mBDbsAccount.WorksType, mWorksQueue.size(), mBlackList.size()));
        }
        return null;

    }



    private boolean writeComment(BFileBase bFileBase){
        bFileBase.UserName = MAPP.getNeatName(6, mBAppUser.UserName);//account.UserName);"手拉着我的儿小罗成【豫剧】"
        bFileBase.WorksName = MAPP.getNeatName(9, mBAppWorks.WorksName);
//        MLOG(String.format("RunB C2 %s(%s)%s(%s)%s(%s)", mBDbsAccount.AccountName, mBDbsAccount.Status, MAPP.gManageLogin, mMyUtils.getServerNumber(), StepTime/1000, Message));
        String careText = RunUtils.checkAutoCare(this);
        String giftText = (GiftDay > 0)  ? RunUtils.checkAutoGift(this) : null;
        String commentText = null;
        LogTyp logTyp = LogTyp.NORMAL_COMMENT;
        if (careText == null && giftText == null){
            switch (logTyp){
                case NORMAL_COMMENT:
                    commentText = RunUtils.getCommentText(NormalComment, NormalCount++);
                    break;
                case NEW_COMMENT:
                    commentText = RunUtils.getCommentText(NewComment, NewCount++);
                    break;
                case OLD_COMMENT:
                    commentText = RunUtils.getCommentText(OldComment, OldCount++);
                    break;
            }
        }
        if (waitWriteLock()) {                  // 等待直至获取到写评论锁
            long tick1 = System.currentTimeMillis();
            setState("点赞");
            if (mBDbsAccount.WorksType < 32) {
                App32.setUser(mBDbsAccount);
            }else if (mBDbsAccount.WorksType < 33) {
                App33.setUser(mBDbsAccount);
            }
            String result1 = addLikeWorks(bFileBase);
            String result2 = null;
            long tick2 = System.currentTimeMillis();
            if (careText != null){                              // 准备开始关注
                setState("关注");
                if (addCareUser(bFileBase)){
                    bFileBase.Text = careText;
                    if (addComment(bFileBase)){
                        result2 = "ok";
                    }
                }
            }else if (giftText != null){                       // 准备开始礼物
                setState("礼物");
                bFileBase.Text = giftText;
                String resGifts = sendGifts(bFileBase);
            }else {                                             // 准备开始评论
                setState("评论");
                bFileBase.Text = commentText;
                if (addComment(bFileBase)){
                    result2 = "ok";
                }
            }
            gWriteTime = (int)(System.currentTimeMillis()-tick1);
            clearWriteLock();                   // 必须记得清除写评论锁

            boolean success = false;
            if ("ok".equals(result2)){
                result2 = MAPP.formatSecond(System.currentTimeMillis() - tick2);
                success = true;
            }
            if (result1 != null){
                bFileBase.WriteTime = String.format("%s评%s", result1, result2);
                saveDoneLog(bFileBase, LogTyp.LOG_LIKE);
                success = true;
            }
            int fileID = MAPI.STRING_DEC32(bFileBase.WorksIdS);
            MLOG(String.format("writeCommentA C %s_%s点赞%s_%04x %s", mBDbsAccount.WorksType, mBDbsAccount.AccountName, bFileBase.UserIdS, fileID, bFileBase.Text));
            MLOG(String.format("writeCommentA D %s_%s %s", mBDbsAccount.WorksType, mBDbsAccount.AccountName, MAPP.formatSecond(gWriteTime)));

            if (careText != null) {
                bFileBase.Text = careText;
                saveDoneLog(bFileBase, LogTyp.CARE_TEXT);
            }else if (giftText != null){
                bFileBase.Text = giftText;
                saveDoneLog(bFileBase, LogTyp.GIFT_TEXT);
            }else {
                bFileBase.Text = commentText;
                saveDoneLog(bFileBase, logTyp);
            }
            bFileBase.Text = String.format("%s-%s %s", bFileBase.WorksName, bFileBase.UserName, bFileBase.Text);
            setMessage(bFileBase.Text, "写入评论");
            return success;
        }
        return false;
    }


    private boolean downloadFile(BFileBase bFileBase){
        if (mBDbsAccount.WorksType == 33) {
            setState("头像");
            bFileBase.HeadFile = App33.downloadHeadFile(mBAppUser);
            return MAPI.isEmpty(bFileBase.HeadFile) ? false : true;
        }
        return false;
    }

    private void saveDoneLog(BFileBase bFileBase, LogTyp logTyp){
        long tick = System.currentTimeMillis();
        MDBS.setDoneLog(mBDbsAccount, logTyp, bFileBase);
        setMessage(String.format("%s", bFileBase.Text), "saveDoneLog");
        mBlackList.add(bFileBase);
        ++mBDbsAccount.SuccessQty;
        ++SuccessQty;
        MDBS.setBDbsAccount(mBDbsAccount);
        tick = System.currentTimeMillis() - tick;
        MLOG(String.format("TaskEachA SuccessQty %s %s %s %sms", mBDbsAccount.WorksType, mBDbsAccount.AccountName, mBDbsAccount.SuccessQty, tick));
    }
    private boolean addComment(BFileBase bFileBase){
        String result = null;
        if (mBDbsAccount.WorksType == 33) {
            result = App33.setComment(bFileBase.UserIdS, bFileBase.WorksIdS, null, bFileBase.Text);
        }else  {
            result = App32.setComment(bFileBase.UserIdS, bFileBase.WorksIdS, null, bFileBase.Text);
        }
        MLOG(String.format("CareGiftComment addComment %s %02x", result, mBDbsAccount.WorksType));
        return checkResult(result, bFileBase);
    }
    private boolean addCareUser(BFileBase bFileBase){
        String result = null;
        if (mBDbsAccount.WorksType == 33) {
            result = App33.addCareUser(bFileBase.UserIdS);
            MLOG(String.format("CareGiftComment addCareUser %s %02x", result, mBDbsAccount.WorksType));
        }else  {
            result = App32.addCareUser(bFileBase.UserIdS);
            MLOG(String.format("CareGiftComment addCareUser %s %02x", result, mBDbsAccount.WorksType));
        }
        return checkResult(result, bFileBase);
    }

    private String addLikeWorks(BFileBase bFileBase){
        if (mBDbsAccount.WorksType < 32) {
            long[] tick = new long[6];
            String[] result = new String[6+1];
            Random random = new Random();
            tick[0] = System.currentTimeMillis();
            int temp = RunUtils.getRandomAbs(57, random);
            result[0] = App32.addDownloadWorks(bFileBase.UserIdS, bFileBase.WorksIdS, RunUtils.getRandomAbs(temp, random));
            tick[0] = System.currentTimeMillis() - tick[0];

            tick[1] = System.currentTimeMillis();
            temp = RunUtils.getRandomAbs(87, random);
            result[1] = App32.addListenWorks(bFileBase.UserIdS, bFileBase.WorksIdS, RunUtils.getRandomAbs(temp, random));
            tick[1] = System.currentTimeMillis() - tick[1];

            tick[2] = System.currentTimeMillis();
            result[2] = App32.addShareWorks(bFileBase.UserIdS, bFileBase.WorksIdS);
            tick[2] = System.currentTimeMillis() - tick[2];

            tick[3] = System.currentTimeMillis();
            result[3] = App32.addCollectWorks(bFileBase.UserIdS, bFileBase.WorksIdS);
            tick[3] = System.currentTimeMillis() - tick[3];

            tick[4] = System.currentTimeMillis();
            temp = RunUtils.getRandomAbs(187, random);
            result[4] = App32.addLikeWorks(bFileBase.UserIdS, bFileBase.WorksIdS, RunUtils.getRandomAbs(temp, random));
            tick[4] = System.currentTimeMillis() - tick[4];

            tick[5] = System.currentTimeMillis();
            BCommentInfo[] bCommentInfos = MDBS.getBCommentList(mBDbsAccount.WorksType, bFileBase.UserIdS, bFileBase.WorksIdS);
            if (bCommentInfos != null && bCommentInfos.length > 0) {
                List<Integer> lists = new ArrayList<>();
                int length = 0;
                do {
                    for (int index = 0; index < bCommentInfos.length; index++) {
                        if ((random.nextInt() & 1) != 0) {
                            lists.add(bCommentInfos[index].CommentID);
                            if (lists.size() > 254) {
                                break;
                            }
                        }
                    }
                    length = lists.size();
                } while (length == 0);
                int[] commentID = new int[length + 1];              // 最后一个INT必须为0
                for (int index = 0; index < length; index++) {
                    commentID[index] = lists.get(index);
//                    ACommentInfo aCommentInfo = new ACommentInfo();
//                    aCommentInfo.UserID = MAPI.STRING_DEC32(bFileBase.UserIdS);
//                    aCommentInfo.FileID = MAPI.STRING_DEC32(bFileBase.WorksIdS);
//                    aCommentInfo.CommentID = commentID[index];
//                    mMyUtils.getCommentText(aCommentInfo);
//                    MSLEEP(100);
//                    MLOG(String.format("writeCommentA commentID %s_%04x_%04x %s", aCommentInfo.UserID, aCommentInfo.FileID, commentID[index], mMyUtils.getCommentText(aCommentInfo)));
                }
                result[5] = App32.addLikeComment(bFileBase.UserIdS, bFileBase.WorksIdS, commentID);
                tick[5] = System.currentTimeMillis() - tick[5];
                MLOG(String.format("writeCommentA addLikeComment %s %s %s %s/%s", mBDbsAccount.WorksType, mBDbsAccount.AccountName, tick[5], length, bCommentInfos.length));
            }
            boolean success = false;
            for (int index = 0; index < tick.length; index++) {
                if ("ok".equals(result[index])){
                    result[index] = MAPP.formatSecond(tick[index]);
                    success = true;
                }else {
                    result[tick.length] = result[index];
                }
            }
            if (success){
                String text = String.format("下%s欣%s享%s藏%s赞%s作%s", result[0], result[1], result[2], result[3], result[4], result[5]);
                return text;
            }
            bFileBase.Text = result[tick.length];
            return null;
        }else if (mBDbsAccount.WorksType == 33) {
            String result = App33.addLikeWorks(bFileBase.WorksIdS);
            MLOG(String.format("addLikeWorksA A %s_%02x点赞%s_%s", mBDbsAccount.UserName, mBDbsAccount.WorksType, bFileBase.UserIdS, result));
//            return checkResult(result, bFileBase);
            return result;
        }
        return null;
    }

    private String sendGifts(BFileBase bFileBase){
        String result;
        if (mBDbsAccount.WorksType < 32) {
            if (MAPP.mKcAGiftBean != null) {
                int giftID = MAPP.mKcAGiftBean[1].FileID;
                int amount = 1;
                result = App32.sendGifts(bFileBase.UserIdS, bFileBase.WorksIdS, giftID, amount, this);
                MLOG(String.format("sendGifts Aa %s_%s_%04x_%04x", mBDbsAccount.UserName, bFileBase.UserIdS, MAPI.STRING_DEC32(bFileBase.WorksIdS), giftID));
                if (gGiftMoney != null) {
                    MLOG(String.format("sendGifts Ab %s_%s_%s_%s_%s", result, gGiftMoney[0], gGiftMoney[1], gGiftMoney[2], gGiftMoney[3]));
                }
                return result;
            }else {
                MLOGE("App32 sendGifts示准备好");
            }
        }else if (mBDbsAccount.WorksType == 33) {
//            MLOG(String.format("giftA 33 sendGifts "));
            result = App33.sendGifts(bFileBase.WorksIdS);
            MLOG(String.format("giftA 33 result %s", result));
            return result;
        }
        return null;
    }
    private boolean checkResult(String result, BFileBase bFileBase){
        if ("ok".equals(result)){
            return true;
        }
        if (result == null){
            if (mBDbsAccount.WorksType == 33) {
                result = App33.getApiError();
            }else {
                result = "";
            }
        }
        bFileBase.Text = result;
        setMessage(String.format("写入出错:%s", result), "checkResult");
//        MDBS.setDoneLog(mBDbsAccount, LogTyp.LOG_FILE, bFileBase);

        if (mBDbsAccount.WorksType < 32) {
            if (result.indexOf("登录") >= 0) {
                mBDbsAccount.Status = result;
                return false;
            }
        }
//        MLOGE(String.format("写入出错:%s", result));


        if (mBDbsAccount.WorksType == 33) {
            if (result.indexOf("封禁") >= 0) {
                mBDbsAccount.Status = "已封禁";
            } else if (result.indexOf("TOKEN") >= 0) {            // ACCESS_TOKEN_INVALID
                mBDbsAccount.Status = "未登录 " + mBDbsAccount.LoginFlag;
//                mAccount33 = new App33(mBDbsAccount);
            } else if (result.indexOf("异常") >= 0) {
                mBDbsAccount.Status = "账号异常";
            } else if (result.indexOf("太多") >= 0) {          // 你发表的评论太多了，请休息一会儿吧:
//                mSetPause = true;
//                if (mSetPause){
                    MLOGE("你发表的评论太多了，请休息一会儿吧:");
                sleepWaitting(60 * 1000);
//                }
            }
            MLOGE(String.format("写入评论出错 %s(%s)", result, mBDbsAccount.Status));
        }
        return false;
    }
    private void checkHoldSetChange(){
        String saveText = null;
        setState("开始");
        while (!MAPP.threadStop && !isStop){
//            MLOG(String.format("RunB Ca %s(%s)%s(%s)%s(%s)", mBDbsAccount.AccountName, mBDbsAccount.Status,  MAPP.gManageLogin, mMyUtils.getServerNumber(), StepTime/1000, Message));
            sleepWaitting(1000);
            String text;
            if (MAPP.gManageLogin != 0 || mMyUtils.getServerNumber() == 0){
                text = String.format("操作号还没有登录，任务暂停(%s_%s)", MAPP.gManageLogin,  mMyUtils.getServerNumber());
            }else if (isPause){
                text = "任务暂停，等待页面完成";
            }else {
//                MLOG(String.format("RunB Cb %s(%s)%s(%s)%s(%s)", mBDbsAccount.AccountName, mBDbsAccount.Status,  MAPP.gManageLogin, mMyUtils.getServerNumber(), StepTime/1000, Message));
                  break;
            }
            setState("暂停");
            if (!text.equals(saveText)) {
                saveText = text;
//                setMessage(text, "checkHold");
            }
            if (RunUtils.checkUploadPlan(this)) {
                uploadWorks();
            }
        }
        int hour = (int) (StepTick / (60 * 60 * 1000));
        if (Hour != hour){              // 每小时
            Hour = hour;
            GiftDay = 100;              // 每天的礼物
//                MLOG(String.format("Change C  %s", mBDbsAccount.LoginFlag));
        }
//mBDbsAccount.Status=" e ";
        if (SetChange){
            SetChange = false;
            if (mBDbsAccount.LoginFlag != null) {
                setState("改变");
                if (mBDbsAccount.Status.indexOf("登录") >= 0) {
//                    String key = getKgAppDbsKey(bDbsAccount, svrType);
//                    String sendText = String.format("0,%s", key);
//                    if (waitWriteLock(0, "管理员_读取")) {
//                        App32.setUser(MSKIN.getMemoryString(W.ManageLoginFlag), 0);
//                        String result = App32.readKgAppDbs(sendText);
//                        clearWriteLock(0);

                }
//                    MLOG(String.format("KgAppDbsA Change B %s(%s)%s(%s)", mBDbsAccount.WorksType, mBDbsAccount.SetConfig[0], mBDbsAccount.UserIdS, mBDbsAccount.LoginFlag));
                WorksQueue.setKgAppDbs(mBDbsAccount, MDBS.SVR_LOGIN);
//                    MLOG(String.format("KgAppDbsA Change D %s(%s)%s(%s)", mBDbsAccount.WorksType, mBDbsAccount.SetConfig[0], mBDbsAccount.UserIdS, mBDbsAccount.LoginFlag));
            }
            String  text = null;
            if (mBDbsAccount.WorksType == 33) {
//                mAccount33 = new App33(mBDbsAccount);
                text = String.format("%s %s", App33.gsToken, App33.gsVersion);
            }else {
//                    mApp32 = new App32(mBDbsAccount);
                text = String.format("%s %s", mBDbsAccount.UserIdS, mBDbsAccount.LoginFlag);
            }
            mBUploadPlan = null;
            MAPP.MLOG_FILE(mBDbsAccount, "开始运行", text);
        }
    }

    private void uploadAndWaitting(){
        boolean once = false;
        while (!isStop){
            long tick2 = (System.currentTimeMillis() - StepTick) + 1000;
            if (SetChange || tick2 > StepTime){
                return;
            }
            if (!once) {            // 只做一次
                once = true;
                if (RunUtils.checkUploadPlan(this)) {
                    uploadWorks();
                }
            }
            sleepWaitting(1000);
        }
    }
    private void uploadWorks(){
        BUploadPlan plan = mBUploadPlan;
        if (plan == null){
            return;
        }
        BUpWorks bUpWorks = plan.mBUpWorks;
        if (bUpWorks == null){
            return;
        }
        MLOG(String.format("UploadA A1 %02x %02x %s IsRelease:%s", mBDbsAccount.WorksType, plan.AppType, plan.WorksName, plan.mBUpWorks.mAFileInfo.IsRelease));
        setPlanMessage(String.format("正在上传%s", plan.WorksName));
        String result = null;
//        MLOG(String.format("UploadA a %s(%s)", bUpWorks.mAFileInfo));
        if (mBDbsAccount.WorksType == 33 && bUpWorks.mAFileInfo instanceof ARecordInfo) {
            ARecordInfo aRecordInfo = (ARecordInfo)bUpWorks.mAFileInfo;
            String fileName = plan.IsVideo ? aRecordInfo.MixVideoFile : aRecordInfo.MixAudioFile;
            MLOG(String.format("UploadA b %s %s", MAPI.GET_FILE_LENGTH(fileName), fileName));
            if (MAPI.IS_FILE_DONE(fileName)){
                MLOG(String.format("UploadA c %s %s", mBDbsAccount.LoginFlag, mBDbsAccount.WorksType));
                if (waitWriteLock()) {                  // 等待直至获取到写评论锁
                    UploadApp33 uploadApp33 = new UploadApp33(mBDbsAccount.LoginFlag, mBDbsAccount.WorksType);
                    uploadApp33.setInfo(mBDbsAccount.UserIdS, mBDbsAccount, plan.WorksName);
                    String setting = uploadApp33.makeSetting(plan.MusicID, plan.WorksName, plan.Intro, plan.Area);
                    result = uploadApp33.uploadMediaFile(plan.IsVideo, fileName, setting);
                    MLOG(String.format("UploadA d %s(%s)", result, setting));
                    clearWriteLock();                   // 必须记得清除写评论锁
                }
            }
        }else  {
            MLOG(String.format("UploadA e %s %s %s", mBDbsAccount.WorksType, mBDbsAccount.AccountName, plan.WorksName));
            UploadWorksTask uploadWorksTask = new UploadWorksTask();
            uploadWorksTask.mRunState = ByteBuffer.allocateDirect(128);
            uploadWorksTask.gpRunState = uploadWorksTask.mRunState.array();
            setState("上传");
            if (plan.mBUpWorks.mAFileInfo != null) {
                if (waitWriteLock()) {                      // 等待直至获取到写评论锁
                    App32.setUser(mBDbsAccount);
                    if (App32.changeUser()) {
                        MLOG(String.format("UploadA QQ %s %s %s", plan.mBUpWorks.UserID, mMyUtils.getCurrentUserID(), mMyUtils.getCurrentLoginUserID()));
                        result = uploadWorksTask.startUpload(plan.mBUpWorks);
                        int flag = -1;
                        int counter = 0;
                        if ("ok".equals(result)){
                            for (counter = 0; counter < 10; counter++) {
                                flag = mMyWorks.threadIsFileReleaseComplete(plan.mBUpWorks.UserID, plan.mBUpWorks.FileID);
                                MLOG(String.format("UploadA QW %s %s %08x", plan.mBUpWorks.UserID, plan.mBUpWorks.FileID, flag));
                                sleepWaitting(1000);
                                if (flag == 0 ){
                                    break;
                                }else {
                                    if (plan.mBUpWorks.WorksType == AWorksType.WORKS_TYPE_PHOTO || plan.mBUpWorks.WorksType == AWorksType.WORKS_BLOG_TEXT) {
                                        if (flag == (1 << KCB_LOST_SUB_NAME)) {             // 缺少subName
                                            break;                                      // 图片博客可以没有歌手名
                                        }
                                    } else if (plan.mBUpWorks.WorksType == AWorksType.WORKS_SING_SONG || plan.mBUpWorks.WorksType == AWorksType.WORKS_RECITATION) {
                                        if (flag == (1 << KCB_LOST_SONG_NAME)) {        // 缺少歌名
                                            break;                                      // 有MusicID0的 可以没有歌手名
                                        }
                                        if (flag == (1 << KCB_LOST_SUB_NAME)) {         // 缺少subName
                                            break;                                      // 有MusicID0的 可以没有歌手名
                                        }
                                    }
                                }
                            }
                        }
                        if (plan.Retry == null){
                            plan.Retry = new ArrayList<>();
                        }
                        plan.Retry.add(String.format("%s_%08x_%s", result, flag, counter));
                    }else {
                        result = mMyUtils.getLastError();
                        if (result.indexOf("登录") >= 0) {
                            mBDbsAccount.Status = result;
                        }
                    }
                    clearWriteLock();                       // 必须记得清除写评论锁
                }
            }else {
                result = "参数不正确";
            }
        }
        if ("ok".equals(result)) {
            plan.DoneTick = System.currentTimeMillis();
            setPlanMessage(String.format("上传作品<%s>完成", plan.WorksName));
        }else {
            String text = String.format("%s_%s上传作品<%s>出错 %s", mBDbsAccount.WorksType, mBDbsAccount.AccountName, plan.WorksName, result);
            setPlanMessage(text);
            MLOGE("UploadA aa " + text);
        }
        MDBS.setBUploadPlan(mBDbsAccount, plan);
        mBUploadPlan = null;
    }

    private void setState(String text){
        long tick = System.currentTimeMillis() - StateTick;
        if (tick > 1000) {
            LastState = String.format("%s%.1f秒", RunState, (float)tick/1000.f);
        }else {
            LastState = String.format("%s%sms", RunState, tick);
        }
        StateTick = System.currentTimeMillis();
        RunState = text;
    }
    private void setMessage(String text, String logMark){
        Message = text;
        MLOG(String.format("%s(RunA mark:%s %s %s)", text, logMark, mBDbsAccount.AccountName, mBDbsAccount.WorksType));
    }
    private void setPlanMessage(String text){
        if (mBDbsAccount != null) {
            mBDbsAccount.Message = text;
        }
        MLOG(text);
    }

    private boolean waitWriteLock(){
        String text = String.format("%s_%s", MAPP.mWorksName[mBDbsAccount.WorksType], mBDbsAccount.AccountName);
        while (!MAPP.threadStop && !isStop) {
            if (mBDbsAccount.WorksType < 32) {
                if (MAPP.lockWrite32(text)) {
                    return true;
                }
            }else if (mBDbsAccount.WorksType == 33) {
                if (MAPP.lockWrite33(text)) {
                    return true;
                }
            }
            sleepWaitting(100);
        }
        return false;
    }
    private void clearWriteLock(){
        if (mBDbsAccount.WorksType < 32) {
            MAPP.lockWrite32(null);
        }else if (mBDbsAccount.WorksType == 33) {
            MAPP.lockWrite33(null);
        }
    }
    private void breakWaitting(){                                    // 退出任何等待
        if (mBDbsAccount != null) {
            synchronized (mBDbsAccount) {                           // 借用对象锁
                mBDbsAccount.notifyAll();
            }
        }
    }
    private void sleepWaitting(int millisecond){                     // 等待毫秒
        synchronized (mBDbsAccount) {                               // 借用对象锁
            try {
                mBDbsAccount.wait(millisecond);                       // 等待信号
            } catch (Exception e) {
            }
        }
    }

}
